﻿using System;
using System.Collections.Generic;
using LogSystem;
using UnityEngine;
using Yoozoo.Framework.Core;
using Yoozoo.Gameplay.Liberty.AI;
using Yoozoo.Gta.Common;
using Yoozoo.HRP.Runtime;
using Yoozoo.Managers.ResourceManagerV2.Runtime;

namespace Yoozoo.Gameplay.Liberty.StreetEvent
{

    [Serializable]
    public class PlayerCacheData
    {
        // 血量
        public int hp;
        // 韧性
        public int reduceToughness;

        public Vector3 position;

        public Vector3 eulerAngles;

    }

    //[Serializable]
    public class StreetEventMonsterData
    {
        public int uniqueId;
        public string counterName;
        public int streetNpcId;
        public SideType sideType;
    }
    
    public class StreetEventManager : SingletonMono<StreetEventManager>
    {
        public const string STREET_EVENT_PART_PATH = "Assets/ResourcesAssets/Hanging/Prefabs/StreetEvent/StreetEvent_";

        public static Action<int> OnKillMonsterAction;

        public StreetEventBase currentEvent;

        public List<StreetTaskCounter> streetTaskCounters;

        public PlayerCacheData playerCacheData;
        
        public VehicleRacingManager vehicleRacingManager;
        
        public Dictionary<int, StreetEventMonsterData> monsterId2InfoMap => _monsterId2InfoMap;
        private Dictionary<int, StreetEventMonsterData> _monsterId2InfoMap = new Dictionary<int, StreetEventMonsterData>(30);

        private ResLoader _eventResLoader;

        private int _bossUniqueId;

        private bool _loadComplete = false;
        
        public void LoadStreetEvent(int streetEventId, Action<int> callback = null)
        {
            string resPath = STREET_EVENT_PART_PATH + streetEventId + ".prefab";
            if (_eventResLoader == null)
            {
                _eventResLoader = ResLoader.Alloc();
            }

            _eventResLoader.Add2Load(resPath, ((success, assetName, asset) =>
            {
                if (!success)
                {
                    Debug.LogError(LogModule.LibertyScene,"加载事件prefab失败：" + assetName);
                    return;
                }

                _loadComplete = false;
                GameObject eventObject =
                    GameObject.Instantiate((asset as GameObject), Vector3.zero, Quaternion.identity, transform);
                vehicleRacingManager = eventObject.GetComponent<VehicleRacingManager>();
                currentEvent = eventObject.GetComponent<StreetEventBase>();
                currentEvent.OnPreInit();
                LibertyAIUtils.PlayerController.RebornPlayer(); // 重置属性
                currentEvent.OnLoad((id =>
                {
                    callback?.Invoke(id);
                    // 现在需求放在这就行了
                    EnterStreetEvent();
                }));
            }));
            _eventResLoader.Load();
        }

        public void OnLoadingComplete()
        {
            if (!_loadComplete)
            {
                StreetEventLoadingComplete.OnLoadingComplete?.Invoke();
                _loadComplete = true;
            }
        }

        public void EnterStreetEvent()
        {
            TimelineManager.OnTimelinePlay += OnTimelinePlay;
            TimelineManager.OnTimelineStop += OnTimelineStop;
            if (currentEvent)
            {
                currentEvent.OnEnter();   
            }
        }

        public void ExitStreetEvent()
        {
            Time.timeScale = 1; // 时间缩放重置
            if (currentEvent)
            {
                currentEvent.OnExit();
                currentEvent.gameObject.SetActive(false);
                GameObject.Destroy(currentEvent.gameObject);
                currentEvent = null;
            }

            if (_eventResLoader != null)
            {
                _eventResLoader.Recycle2Cache();
                _eventResLoader = null;
            }

            if (streetTaskCounters != null)
            {
                streetTaskCounters.Clear();
            }
            
            NpcUniqueIdUtils.Reset();
            StreetTaskCountUtils.Clear();
            
            TimelineManager.OnTimelinePlay -= OnTimelinePlay;
            TimelineManager.OnTimelineStop -= OnTimelineStop;
            
            _monsterId2InfoMap.Clear();
            
            if (vehicleRacingManager != null)
            {
                vehicleRacingManager.Dispose();
                vehicleRacingManager = null;
            }
        }

        public void PauseStreetEvent()
        {
            if (currentEvent)
            {
                currentEvent.OnPause();
            }
        }

        public void ResumeStreetEvent()
        {
            if (currentEvent)
            {
                currentEvent.OnResume();
            }
        }

        public void OnAddMonster(int mId,int streetNpcId, string counterName,SideType sideType)
        {
            if (!_monsterId2InfoMap.ContainsKey(mId))
            {
                _monsterId2InfoMap[mId] = new StreetEventMonsterData()
                {
                    uniqueId = mId,
                    counterName = counterName,
                    streetNpcId = streetNpcId,
                    sideType = sideType,
                };
            }
        }
        public StreetEventMonsterData GetMonsterByUniqueId(int uniqueId)
        {
            if (_monsterId2InfoMap!=null)
            {
                if (_monsterId2InfoMap.TryGetValue(uniqueId,out var data))
                {
                    return data;
                }
            }

            return null;
        }
        public StreetEventMonsterData GetMonster(int streetNpcId)
        {
            if (_monsterId2InfoMap!=null)
            {
                foreach (var monsterData in _monsterId2InfoMap)
                {
                    if (monsterData.Value.streetNpcId == streetNpcId)
                    {
                        return monsterData.Value;
                    }
                }
            }

            return null;
        }

        public int GetStreetMonsterCount()
        {
            int monsterNum = 0;
            foreach (var monsterData in _monsterId2InfoMap)
            {
                if (monsterData.Value.sideType == SideType.Npc ||monsterData.Value.sideType == SideType.Protected || (monsterData.Value.sideType == SideType.Madness))
                {
                    monsterNum++;
                }
            }
            return monsterNum;
        }

        // 获取Boss的AIEntity
        public AIEntity GetBossEntity()
        {
            AIEntity aiEntity = null;
            
            if (_monsterId2InfoMap != null)
            {
                // 先根据记录的ID找
                {
                    StreetEventMonsterData monsterData = null;
                    if(_monsterId2InfoMap.TryGetValue(_bossUniqueId, out monsterData))
                    {
                        aiEntity = LibertyAIUtils.GetNpc(_bossUniqueId);
                        if (aiEntity && aiEntity.data.isBoss)
                        {
                            return aiEntity;
                        }
                    }
                }
                
                // 否则遍历
                foreach (var monsterData in _monsterId2InfoMap)
                {
                    aiEntity = LibertyAIUtils.GetNpc(monsterData.Value.uniqueId);
                    if (aiEntity && aiEntity.data.isBoss)
                    {
                        _bossUniqueId = monsterData.Value.uniqueId;
                        return aiEntity;
                    }
                }
            }

            return null;
        }

        // 缓存玩家在街道场景的相关数据
        public void CachePlayer()
        {
            var player = LibertyAIUtils.GetPlayerEntity();
            playerCacheData = new PlayerCacheData()
            {
                hp = player.data.hp,
                reduceToughness = player.data.reduceToughness,
                
                position =  LibertyAIUtils.PlayerController.Position,
                eulerAngles =  LibertyAIUtils.PlayerController.Rotation.eulerAngles,
            };
        }

        // 还原玩家在街道场景的状态
        public void RevertPlayer()
        {
            if (playerCacheData == null)
            {
                Debug.LogError(LogModule.LibertyScene,"RevertPlayer error");
                return;
            }
            LibertyAIUtils.PlayerController.PlayerTransmission(
                playerCacheData.position,
                 playerCacheData.eulerAngles,
                true,true);
            
            var player = LibertyAIUtils.GetPlayerEntity();
            player.data.hp = playerCacheData.hp;
            player.data.reduceToughness = playerCacheData.reduceToughness;
        }
        
        // Lua层调用
        public void OnCountDownEnd()
        {
            
        }

        public void OnInteractiveAction(int actionId)
        {
            OpenStreetInteractivePanel.OnInteractiveAction?.Invoke(actionId);
        }
        
        public void OnPlayerDead()
        {
            ResidentHandler.Inst.GetFunction("CityLuaFunction.onStreetEventPlayerDead").Action();
        }
        
        public void OnKillMonster(int uniqueId, int killerUniqueId,int weaponId)
        {
            if (uniqueId != LibertyAIUtils.PLAYER_AI_ID)
            {
                AIEntity npc = LibertyAIUtils.GetNpc(uniqueId);
                if (npc && npc.data.isStreetEvent && npc.data.side == SideType.Npc)
                {
                    OnKillMonsterAction?.Invoke(uniqueId);

                    if (_monsterId2InfoMap.TryGetValue(uniqueId,out var d))
                    {
                        if (!string.IsNullOrEmpty(d.counterName))
                        {
                            StreetTaskCountUtils.AddValue(d.counterName, 1);  // 怪物被杀死计数
                        }
                    }
                }
                
            }
            else
            {
                OnPlayerDead();
            }
        }

        private void OnTimelinePlay(string timeLineName)
        {
            ResidentHandler.Inst.GetFunction("CityLuaFunction.pauseEventCountDown").Action();
        }
        
        private void OnTimelineStop(string timeLineName)
        {
            ResidentHandler.Inst.GetFunction("CityLuaFunction.resumeEventCountDown").Action();
            var hCamera = LibertyAIUtils.PlayerController.cameraController.hCamera;
            HCameraManager.EnableCamera(hCamera);
        }

        // 蓝图中的加载项完成，可以关闭Loading界面了
        public void LoadBpStreetEventComplete()
        {
            BlueprintUtils.LoadBpStreetEventComplete(currentEvent.eventConfig.eventID);
        }

        // 蓝图中添加计数器走这个接口，便于可视化调试
        public void AddTaskCounter(string cName, int threshold, TaskCounterMode counterMode, int initCount = 0)
        {
            var counter = StreetTaskCountUtils.AddCounter(cName, threshold, counterMode, initCount);
            if (counter != null)
            {
                if (streetTaskCounters == null)
                {
                    streetTaskCounters = new List<StreetTaskCounter>(10);
                }
                streetTaskCounters.Add(counter);
            }
        }

        // 获取计数器
        public int GetTaskCounter(string cName)
        {
            return StreetTaskCountUtils.GetValue(cName);
        }
        
        // 结算
        public void CompleteEvent()  
        {
            if (currentEvent != null)
            {
                ResidentHandler.Inst.GetFunction("CityLuaFunction.completeStreetEvent").Action(currentEvent.eventConfig.eventID);
            }
        }

        // 开关空气墙
        public void SwitchAirWall(bool enable, string wallName)
        {
            if (currentEvent)
            {
                if (!enable)
                {
                    currentEvent.eventConfig.UnlockAirWall(wallName);
                }
                else
                {
                    currentEvent.eventConfig.RevertAirWall(wallName);
                }
            }
        }

        public void SwitchRacingFender(bool enable)
        {
            currentEvent.eventConfig.SwitchAllRacingFenders(enable);
        }

        public void CreateHittableTarget(int lineId, int spawnPoint, int itype, string resPath, float lifeTime,
            float speed, int score, int head_score, int elite_target)
        {
            StreetEventHittableTargetManager.GetInstance().CreateHittableTarget(lineId, spawnPoint, itype, resPath, lifeTime, speed, score, head_score, elite_target);
        }

        public int GetHoldCupUniqueId()
        {
            if (StreetFightEvent.Instance!=null)
            {
                return StreetFightEvent.Instance.HoldCupUniqueId;
            }

            return 0;
        }
        
        public override void Dispose()
        {
            base.Dispose();
            ResidentHandler.Inst.RemoveFunction("CityLuaFunction.pauseEventCountDown");
            ResidentHandler.Inst.RemoveFunction("CityLuaFunction.resumeEventCountDown");
            ResidentHandler.Inst.RemoveFunction("CityLuaFunction.completeStreetEvent");
            ResidentHandler.Inst.RemoveFunction("CityLuaFunction.onStreetEventPlayerDead");
        }
    }
}